﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Web;
using System.Net;
using System.Text.RegularExpressions;
using System.Globalization;

namespace RapidSpider.DownloadInitialisers
{
    public static partial class DownloadInitialiser
    {
        #region Members
        public static Regex RapidshareComLinkRegex = new Regex(
            "(http://[a-zA-Z0-9\\.]{0,9}rapidshare.com[^\\.\\s]*\\..[^<\"\'\\s&]*)",
            RegexOptions.IgnoreCase);
        public static Regex HotfileComLinkRegex = new Regex(
            "(http://hotfile.com/dl/[^/]*/[^/]*/[^\\.\\s]*\\..[^<\"\'\\s&]*)",
            RegexOptions.IgnoreCase);
        #endregion

        #region Methods
        public static ArrayList GenerateFileList(FileSystemInfo thePath)
        {
            ArrayList theURIList = new ArrayList();

            if (thePath.Exists)
            {
                string theSource =
                    HttpUtility.HtmlDecode(File.ReadAllText(thePath.FullName));

                if (DownloadInitialiser.RapidshareComLinkRegex.IsMatch(theSource))
                {
                    theURIList.AddRange(
                        DownloadInitialiser.GenerateRapidshareComFileList(
                            theSource));
                }
                else if (DownloadInitialiser.HotfileComLinkRegex.IsMatch(theSource))
                {
                    theURIList.AddRange(
                        DownloadInitialiser.GenerateHotfileComFileList(
                            theSource));
                }

            }
            return DownloadInitialiser.RemoveDuplicates(theURIList);
        }

        public static ArrayList GenerateFileList(Uri theURI)
        {
            ArrayList theURIList = new ArrayList();

            if (DownloadInitialiser.RapidshareComLinkRegex.IsMatch(theURI.ToString()))
            {
                theURIList.Add(theURI);
            }
            else if (DownloadInitialiser.HotfileComLinkRegex.IsMatch(theURI.ToString()))
            {
                theURIList.Add(theURI);
            }
            else if (DownloadInitialiser.OutlinkrComLinkRegex.IsMatch(theURI.ToString()))
            {
                return DownloadInitialiser.GenerateFileListFromOutlinkrLink(theURI);
            }
            else if (DownloadInitialiser.LixInLinkRegex.IsMatch(theURI.ToString()))
            {
                return DownloadInitialiser.GenerateFileListFromLixInLink(theURI);
            }
            else
            {
                HttpWebRequest theRequest = (HttpWebRequest)WebRequest.Create(theURI);
                theRequest.UserAgent = "Web-sniffer/1.0.28";

                using (HttpWebResponse theResponse = (HttpWebResponse)theRequest.GetResponse())
                {
                    using (Stream theResponseStream = theResponse.GetResponseStream())
                    {
                        using (StreamReader theStreamReader = new StreamReader(theResponseStream))
                        {
                            string theSource =
                                HttpUtility.HtmlDecode(theStreamReader.ReadToEnd());

                            if (DownloadInitialiser.RapidshareComLinkRegex.IsMatch(theSource))
                            {
                                theURIList.AddRange(
                                    DownloadInitialiser.GenerateRapidshareComFileList(
                                    theSource));
                            }
                            else if (DownloadInitialiser.HotfileComLinkRegex.IsMatch(theSource))
                            {
                                theURIList.AddRange(
                                    DownloadInitialiser.GenerateHotfileComFileList(
                                    theSource));
                            }
                            else if (DownloadInitialiser.LixInLinkRegex.IsMatch(theSource))
                            {
                                theURIList.AddRange(
                                    DownloadInitialiser.GenerateLixInFileList(
                                    theSource)); 
                            }
                            else if (DownloadInitialiser.OutlinkrComLinkRegex.IsMatch(theSource))
                            {
                                theURIList.AddRange(
                                    DownloadInitialiser.GenerateOutlinkrFileList(
                                    theSource));
                            }
                        }
                    }
                }
            }
            return DownloadInitialiser.RemoveDuplicates(theURIList);            
        }

        #region Private Helpers
        private static ArrayList GenerateRapidshareComFileList(
            string theSource)
        {
            ArrayList theURIList = new ArrayList();

            foreach (Match thisMatch in 
                DownloadInitialiser.RapidshareComLinkRegex.Matches(theSource))
            {
                string thisUri = thisMatch.Groups[1].Value;

                if (!thisUri.Contains("...") && !thisUri.Contains("…") && !thisUri.Contains(".cgi"))
                {
                    thisUri = thisUri.Replace(".html", String.Empty);

                    theURIList.Add(new Uri(thisUri));
                }
            }
        
            return theURIList;
        }

        private static ArrayList GenerateHotfileComFileList(
            string theSource)
        {
            ArrayList theURIList = new ArrayList();

            foreach (Match thisMatch in
                DownloadInitialiser.HotfileComLinkRegex.Matches(theSource))
            {
                string thisUri = thisMatch.Groups[1].Value;

                if (!thisUri.Contains("...") && !thisUri.Contains("…") && !thisUri.Contains(".cgi"))
                {
                    thisUri = thisUri.Replace(".html", String.Empty);

                    theURIList.Add(new Uri(thisUri));
                }
            }

            return theURIList;
        }
        
        private static ArrayList RemoveDuplicates(
            ArrayList theInputList)
        {
            Dictionary<Uri, int> theUniqueStore = new Dictionary<Uri, int>();
            ArrayList theFinalList = new ArrayList();

            foreach (Uri thisValue in theInputList)
            {
                if (!theUniqueStore.ContainsKey(thisValue))
                {
                    theUniqueStore.Add(thisValue, 0);
                    theFinalList.Add(thisValue);
                }
            }
            return theFinalList;
        }
        #endregion
        #endregion
    }
}
